<template>
  <div class="default-module">
    <div class="one-module">
      <div class="rev-table">
        <div class="rev-card el-card el-card__body">
          <vxe-toolbar ref="toolbarRef" export print :refresh="{ queryMethod: getList }">
            <template #tools>
              <vxe-button
                :status="expandAll ? 'primary' : ''"
                :circle="true"
                @click="toggleExpandAll"
                icon="vxe-icon-sort"
                class="tool-btn"
                style="margin-right: 12px"
              />
            </template>
            <template #buttons>
              <vxe-button @click="insertRow()">新增</vxe-button>
            </template>
          </vxe-toolbar>
          <div class="main-table">
            <vxe-table
              ref="tableRef"
              show-overflow
              keep-source
              height="auto"
              :column-config="{ resizable: true }"
              :row-config="{
                keyField: 'id',
                useKey: true
              }"
              :tree-config="{
                transform: true,
                expandAll: true,
                reserve: true,
                rowField: 'id',
                parentField: 'parent_id'
              }"
              :edit-config="{ trigger: 'click', mode: 'row', showStatus: true }"
              :edit-rules="validRules"
              :export-config="{}"
              :print-config="{}"
              :custom-config="{}"
              :scroll-y="{ enabled: true }"
              :data="state.tableData"
              @toggle-tree-expand="toggleExpandChangeEvent"
            >
              <vxe-column
                field="menu_name"
                title="菜单名称"
                tree-node
                fixed="left"
                :edit-render="{}"
                width="150"
              >
                <template #edit="{ row }">
                  <vxe-input v-model="row.menu_name" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="menu_type" title="菜单类型" :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-select v-model="row.menu_type" placeholder="默认尺寸">
                    <vxe-option value="目录" label="目录" />
                    <vxe-option value="菜单" label="菜单" />
                    <vxe-option value="按钮" label="按钮" />
                  </vxe-select>
                </template>
              </vxe-column>
              <vxe-column field="permissions" title="权限码" :edit-render="{}" width="120">
                <template #edit="{ row }">
                  <vxe-input v-model="row.permissions" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="path" title="路由地址" :edit-render="{}" width="150">
                <template #edit="{ row }">
                  <vxe-input v-model="row.path" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="component" title="组件路径" :edit-render="{}" width="150">
                <template #edit="{ row }">
                  <vxe-input v-model="row.component" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="query_param" title="路由参数" :edit-render="{}" width="150">
                <template #edit="{ row }">
                  <vxe-input v-model="row.query_param" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="is_frame" title="是否外链" :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-checkbox v-model="row.is_frame" checked-value="是" unchecked-value="否" />
                </template>
              </vxe-column>
              <vxe-column field="is_cache" title="是否缓存" :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-checkbox v-model="row.is_frame" checked-value="是" unchecked-value="否" />
                </template>
              </vxe-column>
              <vxe-column field="visible" title="显示状态" :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-checkbox v-model="row.visible" checked-value="是" unchecked-value="否" />
                </template>
              </vxe-column>
              <vxe-column field="status" title="菜单状态" :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-input v-model="row.status" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="icon" title="菜单图标" :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-input v-model="row.icon" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="remark" title="备注" :edit-render="{}" width="150">
                <template #edit="{ row }">
                  <vxe-input v-model="row.remark" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column field="app_name" title="所属系统" :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-input v-model="row.app_name" mode="text" transfer />
                </template>
              </vxe-column>

              <vxe-column field="order_num" title="排序" sortable :edit-render="{}" width="100">
                <template #edit="{ row }">
                  <vxe-input v-model="row.order_num" mode="text" transfer />
                </template>
              </vxe-column>
              <vxe-column title="操作" fixed="right" width="150" :show-overflow="false">
                <template #default="{ row }">
                  <template v-if="hasUpdateStatus(row) || !row.id || !/^\d+$/.test(row.id)">
                    <el-button type="primary" link status="primary" @click="doSave(row)">
                      保存
                    </el-button>
                    <el-button type="primary" link @click="revertRow(row)"> 取消 </el-button>
                  </template>
                  <template v-else-if="row.id">
                    <el-button type="primary" link @click="insertRow(row, 'bottom')">
                      新增子节点
                    </el-button>
                    <el-button type="primary" link @click="deleteRow(row)"> 删除 </el-button>
                  </template>
                </template>
              </vxe-column>
            </vxe-table>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue'
import { getTableList, addTableData, editTableData, deleteTableData } from '@/api/basic'
import { ElMessageBox } from 'element-plus'

const tableRef = ref()
const toolbarRef = ref()

const state: any = reactive({
  query: {
    page: 1,
    size: 999
  },
  conditions: {},
  source: 'table/sys_menu.yaml',
  config: {},
  orderBy: '',
  tableData: [],
  order: ''
})

// 获取数据
const getList = async () => {
  const res: any = await getTableList({
    as_dict: true,
    ...state.query,
    conditions: state.conditions,
    source: state.source,
    filter: state.config?.filter,
    order: state.orderBy
  })
  state.tableData = res.data
}

getList()

let treeExpandRecords = []
const toggleExpandChangeEvent = (params: any) => {
  const $table = tableRef.value
  if ($table) {
    const { expanded } = params
    treeExpandRecords = $table.getTreeExpandRecords()
    console.log('节点展开事件', expanded, '所有展开的行：', $table.getTreeExpandRecords())
  }
}

const expandAll = ref(false)
const toggleExpandAll = () => {
  const $table = tableRef.value
  if (expandAll.value) {
    $table.clearTreeExpand()
    expandAll.value = false
  } else {
    $table.setAllTreeExpand(true)
    expandAll.value = true
  }
}

const hasUpdateStatus = (row) => {
  const $table = tableRef.value
  if ($table) {
    return $table.isUpdateByRow(row)
  }
}

const insertRow = async (currRow?: any, locat?: string) => {
  const $table = tableRef.value
  if ($table) {
    // 如果 null 则插入到目标节点顶部
    // 如果 -1 则插入到目标节点底部
    // 如果 row 则有插入到效的目标节点该行的位置
    const rid = Date.now()
    if (locat === 'current') {
      const record = {
        id: rid,
        parent_id: currRow.parentId // 父节点必须与当前行一致
      }
      const { row: newRow } = await $table.insertAt(record, currRow)
      await $table.setEditRow(newRow) // 插入子节点
    } else if (locat === 'top') {
      const record = {
        id: rid,
        parent_id: currRow.id // 需要指定父节点，自动插入该节点中
      }
      const { row: newRow } = await $table.insert(record)
      await $table.setTreeExpand(currRow, true) // 将父节点展开
      await $table.setEditRow(newRow) // 插入子节点
    } else if (locat === 'bottom') {
      const record = {
        parent_id: currRow.id // 需要指定父节点，自动插入该节点中
      }
      const { row: newRow } = await $table.insertAt(record, -1)
      await $table.setTreeExpand(currRow, true) // 将父节点展开
      await $table.setEditRow(newRow) // 插入子节点
    } else if (!currRow && !locat) {
      const record = {
        parent_id: '0'
      }
      const { row: newRow } = await $table.insertAt(record, -1)
      await $table.setEditRow(newRow) // 插入子节点
    }
  }
}

const deleteRow = (row) => {
  ElMessageBox.confirm(`确定删除`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      deleteTableData({
        source: state.source,
        id: row.id
      }).then(() => {
        getList()
      })
    })
    .catch(() => {})
}

const doSave = async (row: any) => {
  const isEdit = /^\d+$/.test(row.id)
  const $table = tableRef.value
  const errMap = await $table.validate(row)
  if (errMap) {
    return
  }
  if (isEdit) {
    await editTableData({
      source: state.source,
      fields: row
    })
  } else {
    const res: any = await addTableData({
      source: state.source,
      fields: { ...row, id: undefined }
    })
    const id = res?.id?.[0]
    console.log('-----', id)
  }
  getList()
}

const revertRow = (row: any) => {
  const $table = tableRef.value
  const isEdit = /^\d+$/.test(row.id)
  if (!isEdit) {
    $table.remove(row)
    return
  }
  if ($table) {
    return $table.revertData(row)
  }
}

const validRules = ref({
  menu_name: [{ required: true, message: '' }]
})

onMounted(() => {
  tableRef.value.connect(toolbarRef.value)
})
</script>
